﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.ASPxCallback;

namespace TireService.Web.View.SalesView
{
    public partial class QuotationCalculator : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            if (Page.IsPostBack != true)
            {
                txtExpireDate.Text = DateTime.Now.AddMonths(1).ToShortDateString();
            }

            try
            {
                // Get input parameters for quotation (TireSetId, VF, HF, VB, HB, TireType, Single/Group (TargetGroupType), Business, CustomerId)
                int TireSetId = Convert.ToInt32(Request.QueryString["TireSetId"]);
                int VF = Convert.ToInt32(Request.QueryString["VF"]);
                int HF = Convert.ToInt32(Request.QueryString["HF"]);
                int VB = Convert.ToInt32(Request.QueryString["VB"]);
                int HB = Convert.ToInt32(Request.QueryString["HB"]);
                int TireTypeId = Convert.ToInt32(Request.QueryString["TireType"]);
                int TargetGroupType = Convert.ToInt32(Request.QueryString["TargetGroupType"]);
                bool Business = Convert.ToBoolean(Convert.ToByte(Request.QueryString["Business"]));

                List<BusinessTireSetListView> tires = BindTargetGroupData(db, TireSetId, VF, HF, VB, HB, TireTypeId, TargetGroupType);

                gvTargetCustomers.DataSource = tires;
                gvTargetCustomers.DataBind();
                
                BindVendorPricesData(db, tires);
            }
            catch (Exception ex)
            {
                string test = ex.Message;
                // Some input parameters not valid - redirect customer to QuotationCalculator
                Response.Redirect("QuotationGenerator.aspx");

            }
        }

        private void BindVendorPricesData(TireServiceDB db, List<BusinessTireSetListView> tires)
        {
            // Bind data to vendor price list
            List<TirePriceList> vendorprices = db.GetTirePriceListSpecificTires(db.GetLatestTirePriceList(), Convert.ToDecimal(tires.First().Width), Convert.ToDecimal(tires.First().Height), Convert.ToDecimal(tires.First().Size), Convert.ToInt32(tires.First().TireLoadIndexId), Convert.ToInt32(tires.First().TireSpeedIndexId));

            gvVendorPrices.DataSource = vendorprices;
            gvVendorPrices.DataBind();
        }

        private List<BusinessTireSetListView> BindTargetGroupData(TireServiceDB db, int TireSetId, int VF, int HF, int VB, int HB, int TireTypeId, int TargetGroupType)
        {
            BusinessTireSetListView tireset = db.GetTireSetView(TireSetId);

            if (tireset == null)
            {
                throw new ArgumentException("Hjulsæt ikke fundet");
            }

            // Show data on tireset in GUI
            TireSetBLL tiresetBLL = new TireSetBLL();

            lblType.Text = db.GetTireTypeDescription(tireset.TireTypeId);
            lblDimensions.Text = tiresetBLL.GetTireDimensions(tireset);
            lblLoadIndex.Text = db.GetTireLoadIndexDescription(Convert.ToInt32(tireset.TireLoadIndexId));
            lblSpeedIndex.Text = db.GetTireSpeedIndexDescription(Convert.ToInt32(tireset.TireSpeedIndexId));

            List<BusinessTireSetListView> tires = new List<BusinessTireSetListView>();

            if (TargetGroupType == 1)
            {
                if (Request.QueryString["CustomerId"] != null & Request.QueryString["CustomerId"] != "null")
                {
                    int CustomerId = Convert.ToInt32(Request.QueryString["CustomerId"]);

                    // Prepare quotation calculator for business and specific customer
                    tires = db.BusinessTireSetListViews.Where(p => (p.CustomerId == CustomerId | p.ParentCustomerId == CustomerId) & p.Height == tireset.Height & p.Width == tireset.Width & p.Size == tireset.Size & p.TireSpeedIndexId == tireset.TireSpeedIndexId & p.TireLoadIndexId == tireset.TireLoadIndexId & p.TireTypeId == TireTypeId & p.TireSetStatusId == (int)Shared.TireSetStatus.OnStock & (p.LeftFrontTirePattern <= VF | p.RightFrontTirePattern <= HF | p.LeftRearTirePattern <= VB | p.RightRearTirePattern <= HB)).ToList();
                }
                else
                {
                    // Prepare quotation calculator for selected customers
                    tires = db.BusinessTireSetListViews.Where(p => p.ParentCustomerId == null & p.IsCompany == false & p.Height == tireset.Height & p.Width == tireset.Width & p.Size == tireset.Size & p.TireSpeedIndexId == tireset.TireSpeedIndexId & p.TireLoadIndexId == tireset.TireLoadIndexId & p.TireTypeId == TireTypeId & p.TireSetStatusId == (int)Shared.TireSetStatus.OnStock & (p.LeftFrontTirePattern <= VF | p.RightFrontTirePattern <= HF | p.LeftRearTirePattern <= VB | p.RightRearTirePattern <= HB)).ToList();
                }

                // Get open quotations to check for need of excluding in quotation generator
                List<TireQuotation> activequotations = db.GetTireQuotationActive();

                if (activequotations.Count > 0)
                {
                    foreach (TireQuotation activequotation in activequotations)
                    {
                        foreach (BusinessTireSetListView tire in tires)
                        {
                            if (activequotation.TireSetId == tire.TireSetId)
                            {
                                // Quotation already exist - remove from tire list
                                tires.Remove(tire);
                            }
                        }
                    }
                }
            }
            else
            {
                // Create quotation for single selected customer

                tires.Add(tireset);
            }

            return tires;
        }

        protected void gvTargetCustomers_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            // Get input parameters for quotation (TireSetId, VF, HF, VB, HB, TireType, Single/Group (TargetGroupType), Business, CustomerId)
            int TireSetId = Convert.ToInt32(Request.QueryString["TireSetId"]);
            int VF = Convert.ToInt32(Request.QueryString["VF"]);
            int HF = Convert.ToInt32(Request.QueryString["HF"]);
            int VB = Convert.ToInt32(Request.QueryString["VB"]);
            int HB = Convert.ToInt32(Request.QueryString["HB"]);
            int TireTypeId = Convert.ToInt32(Request.QueryString["TireType"]);
            int TargetGroupType = Convert.ToInt32(Request.QueryString["TargetGroupType"]);
            bool Business = Convert.ToBoolean(Convert.ToByte(Request.QueryString["Business"]));

            List<BusinessTireSetListView> tires = BindTargetGroupData(db, TireSetId, VF, HF, VB, HB, TireTypeId, TargetGroupType);

            gvTargetCustomers.DataSource = tires;
            gvTargetCustomers.DataBind();
        }

        protected void gvTargetCustomers_CustomUnboundColumnData(object sender, ASPxGridViewColumnDataEventArgs e)
        {
            if (e.Column.FieldName == "ReplaceQuantity")
            {
                int txtVF = Convert.ToInt32(Request.QueryString["VF"]);
                int txtHF = Convert.ToInt32(Request.QueryString["HF"]);
                int txtVB = Convert.ToInt32(Request.QueryString["VB"]);
                int txtHB = Convert.ToInt32(Request.QueryString["HB"]);

                int VF = Convert.ToInt32(e.GetListSourceFieldValue("LeftFrontTirePattern"));
                int HF = Convert.ToInt32(e.GetListSourceFieldValue("RightFrontTirePattern"));
                int VB = Convert.ToInt32(e.GetListSourceFieldValue("LeftRearTirePattern"));
                int HB = Convert.ToInt32(e.GetListSourceFieldValue("RightRearTirePattern"));

                int replacequantity = 0;
                if (VF <= txtVF)
                {
                    replacequantity += 1;
                }
                if (HF <= txtHF)
                {
                    replacequantity += 1;
                }
                if (VB <= txtVB)
                {
                    replacequantity += 1;
                }
                if (HB <= txtHB)
                {
                    replacequantity += 1;
                }

                e.Value = replacequantity;
            }
        }

        protected void gvTargetCustomers_DataBound(object sender, EventArgs e)
        {
            ASPxGridView gridView = sender as ASPxGridView;
            gridView.JSProperties["cpReplaceQuantitySummary"] = gridView.GetTotalSummaryValue(gridView.TotalSummary["ReplaceQuantity"]);
        }


        protected void gvVendorPrices_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            // Get input parameters for quotation (TireSetId, VF, HF, VB, HB, TireType, Single/Group (TargetGroupType), Business, CustomerId)
            int TireSetId = Convert.ToInt32(Request.QueryString["TireSetId"]);
            int VF = Convert.ToInt32(Request.QueryString["VF"]);
            int HF = Convert.ToInt32(Request.QueryString["HF"]);
            int VB = Convert.ToInt32(Request.QueryString["VB"]);
            int HB = Convert.ToInt32(Request.QueryString["HB"]);
            int TireTypeId = Convert.ToInt32(Request.QueryString["TireType"]);
            int TargetGroupType = Convert.ToInt32(Request.QueryString["TargetGroupType"]);
            bool Business = Convert.ToBoolean(Convert.ToByte(Request.QueryString["Business"]));

            List<BusinessTireSetListView> tires = BindTargetGroupData(db, TireSetId, VF, HF, VB, HB, TireTypeId, TargetGroupType);

            BindVendorPricesData(db, tires);
        }

        /// <summary>
        /// Callback function that creates quotations and send to customer by email
        /// </summary>
        protected void callBackSendQuotationToCustomer_Callback(object sender, CallbackEventArgs e)
        {
            // Get parameter inputs (0: TirePriceListId, 1: MountingPrice, 2: ProfitMargin, 3: ExpireDate)
            string[] param = e.Parameter.Split('|');

            // TODO: Programmer korrekt aflæsning af parametre - lav desuden input fra klient siden

            // Get input parameters for quotation (TireSetId, VF, HF, VB, HB, TireType, Single/Group (TargetGroupType), Business, CustomerId)
            int TireSetId = Convert.ToInt32(Request.QueryString["TireSetId"]);
            int VF = Convert.ToInt32(Request.QueryString["VF"]);
            int HF = Convert.ToInt32(Request.QueryString["HF"]);
            int VB = Convert.ToInt32(Request.QueryString["VB"]);
            int HB = Convert.ToInt32(Request.QueryString["HB"]);
            int TireTypeId = Convert.ToInt32(Request.QueryString["TireType"]);
            int TargetGroupType = Convert.ToInt32(Request.QueryString["TargetGroupType"]);
            bool Business = Convert.ToBoolean(Convert.ToByte(Request.QueryString["Business"]));
            decimal CostPrice = 0;
            decimal SalesPrice = 0;
            DateTime ExpireDate = Convert.ToDateTime(param[3]);

            // Instantiate database
            TireServiceDB db = new TireServiceDB();

            // Create quotation calculation record
            TireQuotationCalculation quotationcalculation = new TireQuotationCalculation();
            quotationcalculation.TirePriceListId = Convert.ToInt32(param[0]);
            quotationcalculation.MountingPrice = Convert.ToDecimal(param[1]);
            quotationcalculation.TireProfitMargin = Convert.ToDecimal(param[2]);
            quotationcalculation.TireTreadRecommendedChange = VF;

            db.AddTireQuotationCalculation(quotationcalculation);

            // Get selected customer / tires
            List<BusinessTireSetListView> customertargetgroup = BindTargetGroupData(db, TireSetId, VF, HF, VB, HB, TireTypeId, TargetGroupType);

            // Prepare placeholder for created quotations
            List<TireQuotation> tirequotations = new List<TireQuotation>();

            // Create tire quotation for each customer
            foreach (BusinessTireSetListView customertireset in customertargetgroup)
            {
                // Calculate replace quantity
                int replacequantity = 0;
                if (customertireset.LeftFrontTirePattern <= VF)
                {
                    replacequantity += 1;
                }
                if (customertireset.RightFrontTirePattern <= HF)
                {
                    replacequantity += 1;
                }
                if (customertireset.LeftRearTirePattern <= VB)
                {
                    replacequantity += 1;
                }
                if (customertireset.RightRearTirePattern <= HB)
                {
                    replacequantity += 1;
                }

                // Create tire quotation
                TireQuotation tirequotation = new TireQuotation();
                quotationcalculation.TireQuotations.Add(tirequotation);
                tirequotation.CustomerId = Convert.ToInt32(customertireset.CustomerId);
                tirequotation.CarId = Convert.ToInt32(customertireset.CarId);
                tirequotation.TireSetId = Convert.ToInt32(customertireset.TireSetId);
                tirequotation.LeftFrontTirePattern = Convert.ToDecimal(customertireset.LeftFrontTirePattern);
                tirequotation.RightFrontTirePattern = Convert.ToDecimal(customertireset.RightFrontTirePattern);
                tirequotation.LeftRearTirePattern = Convert.ToDecimal(customertireset.LeftRearTirePattern);
                tirequotation.RightRearTirePattern = Convert.ToDecimal(customertireset.RightRearTirePattern);
                tirequotation.TireReplaceQuantity = replacequantity;
                tirequotation.CostPrice = CostPrice;
                tirequotation.SalesPrice = SalesPrice;

                db.AddTireQuotation(tirequotation);

                // Add to placeholder
                tirequotations.Add(tirequotation);
            }

            // Commit changes to database
            db.SubmitChanges();

            // Send quotation to customer
            string TireTypeDescription = db.GetTireTypeDescription(TireTypeId);
            foreach (TireQuotation quotation in tirequotations)
            {
                string AcceptLink = "http://www.mobilhjulskift.dk/GodkendTilbud.aspx?action=1&id=" + quotation.QuotationReferenceId.ToString();
                string RejectLink = "http://www.mobilhjulskift.dk/GodkendTilbud.aspx?action=0&id=" + quotation.QuotationReferenceId.ToString();
                
                string sHF = string.Format("{0:N}", HF);
                string sVF = string.Format("{0:N}", VF);
                string sHB = string.Format("{0:N}", HB);
                string sVB = string.Format("{0:N}", VB);
                string Quantity = quotation.TireReplaceQuantity.ToString();
                decimal tirepriceexvat = quotationcalculation.TireProfitMargin + db.GetTirePriceCostPriceValue(quotationcalculation.TirePriceListId);
                decimal montpriceexvat = quotationcalculation.MountingPrice;
                decimal totalexvat = (tirepriceexvat * quotation.TireReplaceQuantity) + (montpriceexvat * quotation.TireReplaceQuantity);
                decimal vat = totalexvat * Convert.ToDecimal(0.25);
                decimal total = totalexvat * Convert.ToDecimal(1.25);
                string TirePriceExVat = string.Format("{0:N}", tirepriceexvat);
                string TirePriceTotalExVat = string.Format("{0:N}", (tirepriceexvat * quotation.TireReplaceQuantity));
                string MontPriceExVat = string.Format("{0:N}", montpriceexvat);
                string MontPriceTotalExVat = string.Format("{0:N}", (montpriceexvat * quotation.TireReplaceQuantity));
                string TotalExVat = string.Format("{0:N}", totalexvat);
                string TotalVat = string.Format("{0:N}", vat);
                string Total = string.Format("{0:N}", total);
                string ExpireDateDetails = "";
                
                if (quotation.Expiredate != null)
	            {
		            ExpireDateDetails = "Dette tilbud udløber " + ExpireDate.ToShortDateString();
	            }

                string Note = "";

                // Send email to customer
                EmailNotificationServices emailBLL = new EmailNotificationServices();
                emailBLL.SendTireQuotation(db.GetCustomerEmail(quotation.CustomerId), quotation.CustomerId, db.GetCustomerName(quotation.CustomerId), db.GetCarRegistrationNumber(quotation.CarId), TireTypeDescription, Note, string.Format("{0:N}", quotation.RightFrontTirePattern), string.Format("{0:N}", quotation.LeftFrontTirePattern), string.Format("{0:N}", quotation.RightRearTirePattern), string.Format("{0:N}", quotation.LeftRearTirePattern), string.Format("{0:N}", quotationcalculation.TireTreadRecommendedChange), AcceptLink, RejectLink, "TireDescription", string.Format("{0:N}", quotation.TireReplaceQuantity), TirePriceExVat, TirePriceTotalExVat, MontPriceExVat, MontPriceTotalExVat, TotalExVat, TotalVat, Total, ExpireDateDetails);

                quotation.SendOut = DateTime.Now;
                quotation.SendOutCount = 1;
            }

            // Submit changes related to sending emails
            db.SubmitChanges();

            // Dispose database connection
            db.Dispose();
        }
    }
}